package org.jeecg.modules.workorder.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.workorder.entity.WorkingOrder;
import org.jeecg.modules.workorder.entity.WorkingOrderRecord;
import org.jeecg.modules.workorder.mapper.WorkingOrderMapper;
import org.jeecg.modules.workorder.service.IWorkingOrderRecordService;
import org.jeecg.modules.workorder.service.IWorkingOrderService;
import org.jeecg.modules.workorder.vo.OpenBomVO;
import org.jeecg.modules.workorder.vo.OpenWorkingOrderVO;
import org.jeecg.modules.workorder.vo.WorkingOrderPageVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * @Description: 生产工单
 * @Date:   2021-09-09
 * @Version: V1.0
 */
@Service
public class WorkingOrderServiceImpl extends ServiceImpl<WorkingOrderMapper, WorkingOrder> implements IWorkingOrderService {

	@Autowired
	WorkingOrderMapper workingOrderMapper;
	
	@Autowired
	private IWorkingOrderRecordService workingOrderRecordService;
	
	@Override
	public void addWorkingOrder(WorkingOrder workingOrder) {
	   //新增时设置hasChild为0
		workingOrder.setHasChild(IWorkingOrderService.NOCHILD);
		if(oConvertUtils.isEmpty(workingOrder.getPid())){
			workingOrder.setPid(IWorkingOrderService.ROOT_PID_VALUE);
		}else{
			//如果当前节点父ID不为空 则设置父节点的hasChildren 为1
			WorkingOrder parent = baseMapper.selectById(workingOrder.getPid());
			if(parent!=null && !"1".equals(parent.getHasChild())){
				parent.setHasChild("1");
				baseMapper.updateById(parent);
			}
		}
		baseMapper.insert(workingOrder);
	}
	
	@Override
	public void updateWorkingOrder(WorkingOrder workingOrder) {
		WorkingOrder entity = this.getById(workingOrder.getId());
		if(entity==null) {
			throw new JeecgBootException("未找到对应实体");
		}
		String old_pid = entity.getPid();
		String new_pid = workingOrder.getPid();
		if(!old_pid.equals(new_pid)) {
			updateOldParentNode(old_pid);
			if(oConvertUtils.isEmpty(new_pid)){
				workingOrder.setPid(IWorkingOrderService.ROOT_PID_VALUE);
			}
			if(!IWorkingOrderService.ROOT_PID_VALUE.equals(workingOrder.getPid())) {
				baseMapper.updateTreeNodeStatus(workingOrder.getPid(), IWorkingOrderService.HASCHILD);
			}
		}
		baseMapper.updateById(workingOrder);
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteWorkingOrder(String id) throws JeecgBootException {
		//查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if(id.indexOf(",")>0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if(idVal != null){
                	WorkingOrder workingOrder = this.getById(idVal);
                    String pidVal = workingOrder.getPid();
                    //查询此节点上一级是否还有其他子节点
                    List<WorkingOrder> dataList = baseMapper.selectList(new QueryWrapper<WorkingOrder>().eq("pid", pidVal).notIn("id",Arrays.asList(idArr)));
                    if((dataList == null || dataList.size()==0) && !Arrays.asList(idArr).contains(pidVal)
                            && !sb.toString().contains(pidVal)){
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for(String pid : pidArr){
                this.updateOldParentNode(pid);
            }
        }else{
        	WorkingOrder workingOrder = this.getById(id);
            if(workingOrder == null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(workingOrder.getPid());
            baseMapper.deleteById(id);
        }
	}
	
	/**
	 * 查询生产工单数据(树形)，无分页
	 * @param queryWrapper
	 * @return
	 */
	@Override
    public List<WorkingOrder> queryTreeListNoPage(QueryWrapper<WorkingOrder> queryWrapper) {
        List<WorkingOrder> dataList = workingOrderMapper.selectWorkingOrderList(queryWrapper);
        return dataList;
        /*List<WorkingOrderPageVO> mapList = new ArrayList<>();
        for(WorkingOrderPageVO data : dataList){
            String pidVal = data.getPid();
            //递归查询子节点的根节点
            if(pidVal != null && !"0".equals(pidVal)){
            	WorkingOrderPageVO rootVal = this.getTreeRoot(pidVal);
                if(rootVal != null && !mapList.contains(rootVal)){
                    mapList.add(rootVal);
                }
            }else{
                if(!mapList.contains(data)){
                    mapList.add(data);
                }
            }
        }
        return mapList;*/
    }
	
	/**
	 * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
	 * @param pid
	 */
	private void updateOldParentNode(String pid) {
		if(!IWorkingOrderService.ROOT_PID_VALUE.equals(pid)) {
			Integer count = baseMapper.selectCount(new QueryWrapper<WorkingOrder>().eq("pid", pid));
			if(count==null || count<=1) {
				baseMapper.updateTreeNodeStatus(pid, IWorkingOrderService.NOCHILD);
			}
		}
	}

	/**
     * 递归查询节点的根节点
     * @param pidVal
     * @return
     */
    private WorkingOrderPageVO getTreeRoot(String pidVal){
    	WorkingOrderPageVO data =  workingOrderMapper.selectWorkingOrderPageVOById(pidVal);
        if(data != null && !"0".equals(data.getPid())){
            return this.getTreeRoot(data.getPid());
        }else{
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if(pidVal != null){
                if(!sb.toString().contains(pidVal)){
                    if(sb.toString().length() > 0){
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal,sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal,StringBuffer sb){
        List<WorkingOrder> dataList = baseMapper.selectList(new QueryWrapper<WorkingOrder>().eq("pid", pidVal));
        if(dataList != null && dataList.size()>0){
            for(WorkingOrder tree : dataList) {
                if(!sb.toString().contains(tree.getId())){
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(),sb);
            }
        }
        return sb;
    }
    
    /**
     * 通过订单id查询物料分析列表
     */
	@Override
	public List<OpenBomVO> queryBomListByOrderId(String orderId,String styleId) {
		List<OpenBomVO> goldList = workingOrderMapper.queryGoldBomListByOrderId(orderId,styleId);
		List<OpenBomVO> stoneList = workingOrderMapper.queryStoneBomListByOrderId(orderId,styleId);
		List<OpenBomVO> accessoryList = workingOrderMapper.queryAccessoryBomListByOrderId(orderId,styleId);
		List<OpenBomVO> allList = new ArrayList<>();
		allList.addAll(goldList);
		allList.addAll(stoneList);
		allList.addAll(accessoryList);
		return allList;
	}

    /**
     * 通过订单id查询拟生成的开单单列表
     */
	@Override
	public List<OpenWorkingOrderVO> queryOpenListByOrderId(String orderId,String styleId) {
		List<OpenWorkingOrderVO> list = workingOrderMapper.queryOpenListByOrderId(orderId,styleId);
		int i = 0;
		for(OpenWorkingOrderVO vo : list) {
			i++;
			vo.setPn(getPn(i));
		}
		return list;
	}
	


	/**
	 * 合并工单
	 */
	@Override
	@Transactional
	public Result<?> mergeByIds(List<String> ids, LoginUser loginUser) {
		int i = 0;//合并记录数。
		if(!ids.isEmpty()) {
			String workNum ="";
			String orderInfoId ="";
			String styleCusInfoId ="";
			String pid ="";
			//String workNum = String.valueOf(FillRuleUtil.executeRule("work_num_code",null));//工单号
			Integer count = 0;
			BigDecimal withStoneWeight = new BigDecimal("0");//连石重
			BigDecimal pureStoneWeight = new BigDecimal("0");//石重
			BigDecimal goldWeight = new BigDecimal("0");//净金重
			if(!ids.isEmpty()) {
				List<WorkingOrder> list = this.workingOrderMapper.countGroupWorkNumByIds(ids);
				if(!list.isEmpty() && list.size() > 1) {
					return Result.error("合并操作只能是同一工单号下进行！");
				}
				WorkingOrder wo = this.getById(ids.get(0));
				if(wo!=null) {
					 workNum = wo.getWorkNum();
					 orderInfoId = wo.getOrderInfoId();
					 styleCusInfoId = wo.getStyleCusInfoId();
					 pid = wo.getPid(); 
				}
				String max = workingOrderMapper.getMaxPnByOrderInfoId(orderInfoId);
				Integer mergePn = Integer.parseInt(max) + 1;
				String strMergePn = getPn(mergePn);
				
				int size = ids.size();
				for(String id : ids) {
					WorkingOrder workingOrder = this.getById(id);
					if(workingOrder.getCount() == 0) {//如果该工单的存货数量为0，则跳过，不合并该工单。
						if(size == 2) {//如果只有两条工单并且有一条工单的存货数量是0，则合并操作无意义，无需执行。
							break;
						} else {
							continue;
						}
					}
					i++;
					count += workingOrder.getCount();//合并数量
					
					WorkingOrderRecord workingOrderRecord = workingOrderRecordService.getById(workingOrder.getCurrWorkingOrderRecordId());
					if(workingOrderRecord != null) {
						if(workingOrderRecord.getWithStoneWeight() != null) {
							withStoneWeight = withStoneWeight.add(workingOrderRecord.getWithStoneWeight());
						}
						if(workingOrderRecord.getPureStoneWeight() != null) {
							pureStoneWeight = pureStoneWeight.add(workingOrderRecord.getPureStoneWeight());
						}
						if(workingOrderRecord.getGoldWeight() != null) {
							goldWeight = goldWeight.add(workingOrderRecord.getGoldWeight());
						}
					}
					
					
					UpdateWrapper<WorkingOrder> updateWrapper = new UpdateWrapper<>();
					updateWrapper.set("is_merged", "1");//设置合并状态为被合并
					updateWrapper.set("store_status", null);//设置存货状态为空
					updateWrapper.set("merged_worknum_and_pn",workNum+","+strMergePn);//合并后的工单号和拆分页码
					updateWrapper.eq("id", id);
					this.update(updateWrapper);
					
					
					UpdateWrapper<WorkingOrderRecord> updateRecordWrapper = new UpdateWrapper<>();
					updateRecordWrapper.set("store_status", null);
					updateRecordWrapper.eq("id", workingOrder.getCurrWorkingOrderRecordId());
					workingOrderRecordService.update(updateRecordWrapper);
				}
				
				WorkingOrder mergeWorkingOrder = new WorkingOrder();
				mergeWorkingOrder.setCount(count);
				mergeWorkingOrder.setWorkNum(workNum);//工单号
				mergeWorkingOrder.setOrderInfoId(orderInfoId);//订单ID
				mergeWorkingOrder.setStyleCusInfoId(styleCusInfoId);//款式ID
				mergeWorkingOrder.setPn(strMergePn);//拆分页
				mergeWorkingOrder.setWorkOrderType(8);//工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
				mergeWorkingOrder.setStoreBy(wo.getStoreBy());//存货人
				mergeWorkingOrder.setStoreDept(wo.getStoreDept());//存货部门
				mergeWorkingOrder.setStoreStatus(1);//状态：1存货、2报废、3交货
				mergeWorkingOrder.setPid(pid);//根节点
				mergeWorkingOrder.setStyleImageString(wo.getStyleImageString());//图片
				mergeWorkingOrder.setStyleCodeNum(wo.getStyleCodeNum());//款号
				this.save(mergeWorkingOrder);
				
				
				/**合并工单后，要生成一条新的交收记录*/
				WorkingOrderRecord workingOrderRecord = new WorkingOrderRecord();
				Date nowTime = new Date();
				workingOrderRecord.setCount(count);//数量
				workingOrderRecord.setParentId("0");//默认是根节点
				workingOrderRecord.setWorkOrderType(8);//工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
				workingOrderRecord.setPn(strMergePn);//拆分页
				workingOrderRecord.setWorkNum(workNum);//工单号
				workingOrderRecord.setSendBy(wo.getStoreBy());// 发送人
				workingOrderRecord.setSendDept(wo.getStoreDept());// 发送部门
				workingOrderRecord.setSendTime(nowTime);// 发送时间
				workingOrderRecord.setReceiveBy(wo.getStoreBy());// 接收人
				workingOrderRecord.setReceiveDept(wo.getStoreDept());// 接收部门
				workingOrderRecord.setReceiveTime(nowTime);// 接收时间
				workingOrderRecord.setStoreStatus(1);//状态：1存货、2报废、3交货
				workingOrderRecord.setWithStoneWeight(withStoneWeight);//连石重
				workingOrderRecord.setPureStoneWeight(pureStoneWeight);//石重
				workingOrderRecord.setGoldWeight(goldWeight);//金重
				workingOrderRecord.setWorkingOrderId(mergeWorkingOrder.getId());// 工单ID
				workingOrderRecordService.addWorkingOrderRecord(workingOrderRecord);// 写入数据库，保存数据
				
				WorkingOrder updateWorkingOrder = new WorkingOrder();
				updateWorkingOrder.setCurrWorkingOrderRecordId(workingOrderRecord.getId());
				updateWorkingOrder.setId(mergeWorkingOrder.getId());
				this.updateById(updateWorkingOrder);// 写入数据库，保存数据
			}
		}
		return i > 0 ? Result.OK("合并工单成功！") : Result.error("合并工单失败！");
	}
	

	/**
	 * 通过订单id获取下一拆分页
	 */
	@Override
	public String getNextStartPn(String orderInfoId) {
		String currMaxPnString = workingOrderMapper.getMaxPnByOrderInfoId(orderInfoId);
		Integer nextPnInteger = Integer.parseInt(currMaxPnString) + 1;
		return this.getPn(nextPnInteger);
	}

	
	/**
	 * 获取拆分页（字符数字形式，不足两位的前面补0）
	 * @param pn
	 * @return
	 */
	private String getPn(Integer pn) {
		if(pn < 10) {
			return "0"+String.valueOf(pn);
		} else {
			return String.valueOf(pn);
		}
	}

	/**
	 * 查询生产工单数据，分页
	 */
	@Override
	public IPage<WorkingOrder> page(Page<WorkingOrder> page,
			QueryWrapper<WorkingOrder> queryWrapper) {
		return workingOrderMapper.selectWorkingOrderPage(page, queryWrapper);// 分页对象
	}

	/**
	 * 通过工单号查询
	 */
	@Override
	public Map<String,String> queryByWorknum(String workNum) {
		return workingOrderMapper.queryByWorknum(workNum);
	}
}
